from java.awt import BorderLayout
from javax.swing import AbstractAction, JButton, JComponent, JTextField, KeyStroke

class SchmuckHistoryPrevAction(AbstractAction):
	def __init__(self, buffer):
		self.buffer = buffer

	def actionPerformed(self, action_event):
		self.buffer.prev()

class SchmuckHistoryNextAction(AbstractAction):
	def __init__(self, buffer):
		self.buffer = buffer

	def actionPerformed(self, action_event):
		self.buffer.next()
	
class SchmuckHistoryBuffer(object):
	def __init__(self, input_component):
		self.input_component = input_component
		self.buffer = []
		self.max_buffer_size = 100
		self.buffer_position = -1

	def next(self):
		if(self.buffer_position > -1):
			self.buffer_position = self.buffer_position - 1
			if(self.buffer_position < 0):
				self.input_component.textfield.setText("")
			else:
				self.input_component.textfield.setText(self.buffer[self.buffer_position])

	def prev(self):
		if(self.buffer_position < (len(self.buffer) - 1)):
			self.buffer_position = self.buffer_position + 1
			self.input_component.textfield.setText(self.buffer[self.buffer_position])
			
	def add(self, line):
		text = self.input_component.textfield.getText()
		if(len(self.buffer) == 0 or self.buffer[self.buffer_position] != text):
			self.buffer.insert(0, text)
			self.buffer_position = -1
		if(len(self.buffer) > self.max_buffer_size):
			del self.buffer[len(self.buffer) - 1]

class SchmuckInputComponentSendAction(AbstractAction):
	def __init__(self, command_processor, input_component, callback):
		self.command_processor = command_processor
		self.input_component = input_component
		self.callback = callback
		self.putValue(self.NAME, "Send")
		self.putValue(self.SHORT_DESCRIPTION, "Send text to the connection")

	def actionPerformed(self, action_event):
		try:
			text = self.command_processor.run_command(self.input_component.textfield.getText())
			if(text is not False):
				self.input_component.history_buffer.add(text)
				self.callback.receive_line(text)
			self.input_component.textfield.setText("")
		except:
			raise

class SchmuckInputComponent(JComponent):
	def __init__(self, command_processor, callback):
		self.history_buffer = SchmuckHistoryBuffer(self)
		self.send_action = SchmuckInputComponentSendAction(command_processor, self, callback)
		self.history = []
		self.history_index = 0
		self.history_maximum = 100
		
		self.setLayout(BorderLayout())
		self.textfield = JTextField(80)
		self.sendbutton = JButton("Send")
		
		self.textfield.addActionListener(self.send_action)
		self.sendbutton.addActionListener(self.send_action)
				
		self.add(self.textfield, BorderLayout.CENTER)
		self.add(self.sendbutton, BorderLayout.EAST)
		
		self.textfield.getActionMap().put("prev-in-history", SchmuckHistoryPrevAction(self.history_buffer))
		self.textfield.getActionMap().put("next-in-history", SchmuckHistoryNextAction(self.history_buffer))

	def bind(self, key, action_name):
		self.textfield.getInputMap().put(KeyStroke.getKeyStroke(key), action_name)